#include "hplcqinfinemakepacket.h"
#include "hplcqinfinepacketformat.h"
#include "hplcqinfinepfcid.h"
#include "hplcqinfinefindpacket.h"
#include "common/convert.h"
#include "common/str.h"

#include "hplcqinfineprotocolcommondata.h"

namespace hplc
{
namespace qinfine
{

HplcQinfineMakePacket::HplcQinfineMakePacket(HplcQinfineProtocolCommonData &data)
{
    m_d = &data;
}

void HplcQinfineMakePacket::makeGlobalPacket(quint8 pfc)
{
    m_d->m_txBufferHex.clear();
    m_d->m_txBufferHex.append(GLOBAL_ADDRESS);
    m_d->m_txBufferHex.append((char)pfc);
    postMakePacket();
}

void HplcQinfineMakePacket::makeGlobalPacket(quint8 pfc, quint8 para)
{
    m_d->m_txBufferHex.clear();
    m_d->m_txBufferHex.append(GLOBAL_ADDRESS);
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint16 para)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    append2Bytes((char*)(&para));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, quint8 para2)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    m_d->m_txBufferHex.append((char)para2);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, quint8 para2, qint32 para3)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    m_d->m_txBufferHex.append((char)para2);
    append4Bytes((char*)(&para3));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, quint32 para2)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    append4Bytes((char*)(&para2));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint16 para, quint16 para2)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    append2Bytes((char*)(&para));
    append2Bytes((char*)(&para2));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint16 para, quint16 para2, quint8 para3)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    append2Bytes((char*)(&para));
    append2Bytes((char*)(&para2));
    m_d->m_txBufferHex.append((char)para3);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint32 para)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    append4Bytes((char*)(&para));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, float para)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    append4Bytes((char*)(&para));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, float para, float para2)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    append4Bytes((char*)(&para));
    append4Bytes((char*)(&para2));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, char *str)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    appendString(str);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, char *str)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    appendString(str);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, float para2)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    append4Bytes((char*)(&para2));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, quint8 para2, quint32 para3)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    m_d->m_txBufferHex.append((char)para2);
    append4Bytes((char*)(&para3));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, float para2, float para3)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    append4Bytes((char*)(&para2));
    append4Bytes((char*)(&para3));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, float para2, quint8 para3)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    append4Bytes((char*)(&para2));
    m_d->m_txBufferHex.append((char)para3);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, quint8 para2, quint8 para3)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    m_d->m_txBufferHex.append((char)para2);
    m_d->m_txBufferHex.append((char)para3);
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, quint16 para2)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    append2Bytes((char*)(&para2));
    postMakePacket();
}

void HplcQinfineMakePacket::makePacket(quint8 pfc, quint8 para, qint32 para2)
{
    preMakePacket();
    m_d->m_txBufferHex.append((char)pfc);
    m_d->m_txBufferHex.append((char)para);
    append4Bytes((char*)(&para2));
    postMakePacket();
}


void HplcQinfineMakePacket::append2Bytes(char *para)
{
    m_d->m_txBufferHex.append(para[1]);
    m_d->m_txBufferHex.append(para[0]);
}

void HplcQinfineMakePacket::append4Bytes(char *para)
{
    m_d->m_txBufferHex.append(para[3]);
    m_d->m_txBufferHex.append(para[2]);
    m_d->m_txBufferHex.append(para[1]);
    m_d->m_txBufferHex.append(para[0]);
}

void HplcQinfineMakePacket::appendString(char *str)
{
    while (*str != NULL)
    {
        m_d->m_txBufferHex.append(*str++);
    }
    m_d->m_txBufferHex.append(*str);
}

void HplcQinfineMakePacket::addCRC()
{
#if(CRC16_ENABLE)
    quint16 crc = 0xFFFF;
    str::addCRC16((uint8_t*)(m_d->m_txBufferHex.data()), m_d->m_txBufferHex.size(), &crc);
    m_d->m_txBufferHex.append((char)(crc >> 8));
    m_d->m_txBufferHex.append((char)crc);
#endif
}

void HplcQinfineMakePacket::toAscii()
{
    m_d->m_txBuffer.clear();
    m_d->m_txBuffer.resize(m_d->m_txBufferHex.size() * 2);
    Convert::Hex2Ascii((uint8_t*)(m_d->m_txBuffer.data()), (uint8_t*)(m_d->m_txBufferHex.data()), m_d->m_txBufferHex.size());
}

void HplcQinfineMakePacket::addHeadAndTail()
{
    m_d->m_txBuffer.prepend(SYSTEM_COMMUNICATE_HEAD);
    m_d->m_txBuffer.append(SYSTEM_COMMUNICATE_TAIL);
}

void HplcQinfineMakePacket::preMakePacket()
{
    m_d->m_txBufferHex.clear();
    m_d->m_txBufferHex.append(m_d->m_address);
}

void HplcQinfineMakePacket::postMakePacket()
{
    addCRC();
    toAscii();
    addHeadAndTail();
}

} // qinfine
} // hplc
